/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Ordinal Comparer Class
 *      Compares ordinal position strings.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using System.IO;
using System.Globalization;

namespace Adaptive.Foundation 
{
    /// <summary>
    /// Compares ordinal position strings.
    /// </summary>
    [Serializable]
    public sealed class OrdinalComparer : StringComparer
    {
        /*------------------------------------------------------------------------
         * Private Member Declarations
         *----------------------------------------------------------------------*/
        #region Private Member Declarations
        /// <summary>
        /// Ignore string casing flag.
        /// </summary>
        private bool _ignoreCase;
        #endregion

        /*------------------------------------------------------------------------
		 * Constructor / Dispose / Destructor Methods
		 *----------------------------------------------------------------------*/
        #region Constructor / Dispose / Destructor Methods
        /// <summary>
        /// Initializes a new instance of the class
        /// </summary>
        /// <remarks>
        /// This is the default constructor.
        /// </remarks>
        public OrdinalComparer(bool ignoreCase)
        {
            _ignoreCase = ignoreCase;
        }
        #endregion

        /*------------------------------------------------------------------------
		 * Public Methods / Functions
		 *----------------------------------------------------------------------*/
        #region Public Methods / Functions
        /// <summary>
        /// Compares one ordinal string with another.
        /// </summary> 
        /// <param name="x">
        /// The left ordinal string to be compared.
        /// </param>
        /// <param name="y">
        /// The right ordinal string to be compared/
        /// </param>
        /// <returns>
        /// Zero (0) if the two items are equal; less than zero if the left value 
        /// is less then the right value, or greater than zero if the left value
        /// is greater than the right value.
        /// </returns>
        public override int Compare(string x, string y)
        {
            int returnValue = 0;                    //Return value.

            //Compare references.
            if (object.ReferenceEquals(x, y))
                returnValue = 0;
            
            else if (x == null)
                returnValue = -1;

            else if (y == null)
                returnValue = 1;
            
            if (_ignoreCase)
            {
                returnValue = string.CompareOrdinal(
                    ((string)x).ToLower(), ((string)y).ToLower());
            }
            else
                returnValue = string.CompareOrdinal(x, y);

            return returnValue;
        }
        /// <summary>
        /// Indicates whether two objects are equal.
        /// </summary>
        /// <param name="obj">
        /// A <see cref="OrdinalComparer"/> instance to compare the current
        /// instance against.
        /// </param>
        /// <returns>
        /// <b>true</b> if the two items are equal; otherwise, returns <b>false</b>.
        /// </returns>
        public override bool Equals(object obj)
        {
            OrdinalComparer rightValue = null;          //Re-cast variable.
            bool returnValue = false;                   //Return value.
            
            //Ensure type is correct.  Items cannot be equal if they are not
            //of the same type.
            rightValue = obj as OrdinalComparer;
            if (rightValue != null)
                returnValue = _ignoreCase == rightValue._ignoreCase;

            return returnValue;
        }
        /// <summary>
        /// Compares two ordinal string values to determine if they are equal.
        /// </summary>
        /// <param name="x">
        /// The left string to be compared.
        /// </param>
        /// <param name="y">
        /// The right string to be compared.
        /// </param>
        /// <returns>
        /// <b>true</b> if the two strings are equal; otherwise, returns <b>false</b>.
        /// </returns>
        public override bool Equals(string x, string y)
        {
            bool returnValue = false;               //Return value.

            returnValue = object.ReferenceEquals(x, y);
            if (!returnValue)
            {
                if ((x == null) || (y == null))
                    //If one item is null; items cannot be equal.
                    returnValue = false;

                else if (x.Length != y.Length)
                    //Must be same length.
                    returnValue = false;

                else if (_ignoreCase)
                    //Compare.
                    returnValue = x.Equals(y);

            }

            return returnValue;
        }
        /// <summary>
        /// Returns a hash code for the current instance.
        /// </summary>
        /// <returns>
        /// A hash code value.
        /// </returns> 
        public override int GetHashCode()
        {
            string typeName = this.GetType().Name;  //Type name.
            int hashValue = 0;                      //Return value.

            //Get hash code based on type name.
            hashValue = typeName.GetHashCode();

            //Modify return value based on prpperty setting.
            if (!_ignoreCase)
                hashValue = ~hashValue;

            return hashValue;
        }
        /// <summary>
        /// Gets a hash code for the provided object instance.
        /// </summary>
        /// <param name="obj">
        /// An object to retrieve a hash code for.
        /// </param>
        /// <returns>
        /// A hash code value.
        /// </returns>
        public override int GetHashCode(string obj)
        {
            int returnValue = 0;                    //Return value.

            if (obj == null)
                throw new ArgumentNullException("obj");
            else
                returnValue = obj.GetHashCode();

            return returnValue;
        }
        #endregion
    }
}
